package com.derbysoft.lowcostadapter.dswitch2.translator.impl;

import com.derbysoft.lowcostadapter.commons.dto.*;
import com.derbysoft.lowcostadapter.commons.model.Hotel;
import com.derbysoft.lowcostadapter.commons.utils.DateTimeUtils;
import com.derbysoft.lowcostadapter.dswitch2.service.helper.GuestCountUtils;
import com.derbysoft.lowcostadapter.dswitch2.translator.Translator;
import com.derbysoft.remote.dswitch.core.GenericRQ;
import com.derbysoft.remote.dswitch.hotel.dto.GuestCountDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelAvailCriteriaDTO;
import com.derbysoft.remote.dswitch.hotel.dto.HotelAvailRQ;
import com.derbysoft.remote.dswitch.hotel.dto.StayDateRangeDTO;
import org.springframework.stereotype.Component;

import java.util.List;

@Component("ds2HotelAvailRQTranslator")
public class HotelAvailRQTranslatorImpl extends AbstractRQTranslator implements Translator<GenericRQ<HotelAvailRQ>, Search, Hotel> {
    private static final int DEFAULT_CHILD_AGE = 10;

    @Override
    public Search translate(GenericRQ<HotelAvailRQ> rq, Hotel hotel) {
        Search search = new Search();
        search.setSearchRequest(createSearchRequest(rq, hotel));
        return search;
    }

    private SearchRequest createSearchRequest(GenericRQ<HotelAvailRQ> rq, Hotel hotel) {
        HotelAvailCriteriaDTO hotelAvailCriteriaDTO = rq.getPayload().getAvailCriteria();
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.setLoginDetails(createLoginDetails(rq.getHeader().getSource().getUniqueID().getId()));
        searchRequest.setSearchDetails(createSearchDetails(hotelAvailCriteriaDTO, hotel));
        return searchRequest;
    }

    private SearchDetails createSearchDetails(HotelAvailCriteriaDTO hotelAvailCriteriaDTO, Hotel hotel) {
        SearchDetails searchDetails = new SearchDetails();

        searchDetails.setPropertyID(hotel.getPropertyID());

        StayDateRangeDTO stayDateRangeDTO = hotelAvailCriteriaDTO.getStayDateRange();
        searchDetails.setArrivalDate(DateTimeUtils.formatDate(
                stayDateRangeDTO.getCheckInDate()));
        searchDetails.setDuration(
                DateTimeUtils.getIntervalDays(
                        stayDateRangeDTO.getCheckInDate(),
                        stayDateRangeDTO.getCheckOutDate()).intValue());

        searchDetails.setRoomRequests(createRoomRequests(hotelAvailCriteriaDTO));

        return searchDetails;
    }

    private ArrayOfRoomRequest createRoomRequests(HotelAvailCriteriaDTO hotelAvailCriteriaDTO) {
        ArrayOfRoomRequest arrayOfRoomRequest = new ArrayOfRoomRequest();
        for (int roomIndex = 0; roomIndex < hotelAvailCriteriaDTO.getRoomStayCandidates().getNumberOfUnits(); roomIndex++) {
            arrayOfRoomRequest.getRoomRequest().add(createRoomRequest(hotelAvailCriteriaDTO));
        }
        return arrayOfRoomRequest;
    }

    private RoomRequest createRoomRequest(HotelAvailCriteriaDTO hotelAvailCriteriaDTO) {
        RoomRequest roomRequest = new RoomRequest();

        List<GuestCountDTO> guestCounts = hotelAvailCriteriaDTO.getRoomStayCandidates().getGuestCounts();
        roomRequest.setAdults(GuestCountUtils.getAdults(guestCounts));

        roomRequest.setChildren(GuestCountUtils.getChildren(guestCounts));

        if (roomRequest.getChildren() > 0) {
            ArrayOfChildAge arrayOfChildAge = new ArrayOfChildAge();
            for (int childIndex = 0; childIndex < roomRequest.getChildren(); childIndex++) {
                arrayOfChildAge.getChildAge().add(createChildAge(DEFAULT_CHILD_AGE));
            }
            roomRequest.setChildAges(arrayOfChildAge);
        }

        return roomRequest;
    }

    private ChildAge createChildAge(int age) {
        ChildAge childAge = new ChildAge();
        childAge.setAge(age);
        return childAge;
    }
}
